using ABA;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;

namespace FW
{
    public class ConverConfig
    {
        public static void GenCSharp(List<SettingItem> list)
        {
            if (!Directory.Exists(Path_ExcelSetting.ExcelFolder))
            {
                if (!Directory.Exists(Path_ExcelSetting.GenCSharpFolder))
                    Directory.CreateDirectory(Path_ExcelSetting.GenCSharpFolder);

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                foreach (var item in list)
                {
                    GenCSharp(item);

                }
                stopwatch.Stop();
                int s = (int)stopwatch.ElapsedMilliseconds / 1000;
                EditorUtility.DisplayDialog("提示", $"生成CSharp，时间{s}", "好的");
            }
            else
            {
                if (EditorUtility.DisplayDialog("提示", "配表路径有问题，请检查", "这就去"))
                {
                    SettingWind.ShowWindow(Path_ExcelSetting.TAG);
                }
            }
        }

        public static void GenCSharp(SettingItem item)
        {
            ///生成西沙普代码
            if (Directory.Exists(Path_ExcelSetting.ExcelFolder))
            {
                var list = GetTableData(item);
                for(int i = 0; i < list.Count; i++)
                {
                    var data = list[i];
                    string str_csharpContent = GetCSharpString(data);
                    string csFilePath = $"{Path_ExcelSetting.GenCSharpFolder}/Config_{data._tableName}.cs";
                    if(!Directory.Exists(csFilePath))
                        Directory.CreateDirectory(csFilePath);
                    File.WriteAllText(csFilePath, str_csharpContent);


                }
            }
        }
        /// <summary>
        /// 只生成cs类，但cs类的实例化 以及与配置表数据实际对应上，也就是一个Item_FileName 与Excel一条记录对应 还需要导入操作
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static string GetCSharpString(ExcelTableData data)
        {
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < data._fieldNameList.Count; i++)
            {
                sb.AppendLine("\t\t/// <summary>");
                sb.Append("\t\t/// " + data._fieldNameList[i]);
                if (!string.IsNullOrEmpty(data._commentList[i]))
                    sb.AppendFormat("({0})", data._commentList[i]);
                sb.AppendLine();
                sb.AppendLine("\t\t /// <summary>");
                sb.Append("\t\tpublic ");
                switch (data._typeNameList[i].ToLower())
                {
                    case "byte": sb.Append("short "); break;
                    case "string": sb.Append("string "); break;
                    case "bool": sb.Append("bool "); break;
                    case "int":
                    case "int32": sb.Append("int "); break;
                    case "uint":
                    case "uint32": sb.Append("uint "); break;
                    case "int64":
                    case "long": sb.Append("long "); break;
                    case "datetime": sb.Append("DateTime "); break;
                    case "float": sb.Append("float "); break;
                    case "double": sb.Append("double "); break;


                    case "byte[]": sb.Append("short[] "); break;
                    case "string[]": sb.Append("string[] "); break;
                    case "bool[]": sb.Append("bool[] "); break;
                    case "int[]":
                    case "int32[]": sb.Append("int[] "); break;
                    case "uint[]":
                    case "uint32[]": sb.Append("uint[] "); break;
                    case "int64[]":
                    case "long[]": sb.Append("long[] "); break;
                    case "datetime[]": sb.Append("DateTime[] "); break;
                    case "float[]": sb.Append("float[] "); break;
                    case "double[]": sb.Append("double[] "); break;


                    // TODO:longer Unity ScriptableObject 不能直接存储字典和二维数组 ！！！！！！！
                    // case "byte[,]": sb.Append("short[,] "); break;
                    // case "string[,]": sb.Append("string[,] "); break;
                    // case "bool[,]": sb.Append("bool[,] "); break;
                    // case "int[,]":
                    // case "int32[,]": sb.Append("int[,] "); break;
                    // case "uint[,]":
                    // case "uint32[,]": sb.Append("uint[,] "); break;
                    // case "int64[,]":
                    // case "long[,]": sb.Append("long[,] "); break;
                    // case "datetime[,]": sb.Append("DateTime[,] "); break;
                }
                sb.Append(data._fieldNameList[i]);
                sb.AppendLine(";");
            }

           

            string res = sb.ToString();
            return res;
        }

        public static List<ExcelTableData>GetTableData(SettingItem item)
        {
            return GetTableData(item.name);
        }
        public static List<ExcelTableData> GetTableData(string excelName)
        {
            var decoder = new DecodeExcel();
            return decoder.Decode($"{Path_ExcelSetting.ExcelFolder}/{excelName}");
        }


        static string error_template = @"
/*代码自动生成的类，请勿手动修改*/
namespace FW
{
    public class ErrorConst
    {
        {ITEM_LIST}
    }
}
";
        static string error_template_item = @"
        public static int {NAME} = {ERROR};
";


        static string excelGen_template = @"
/// <summary>
/// 本文件中的代码为自动生成，请勿修改,修改也无效
/// </summary>
using System;
using System.Collections;
using UnityEngine;

namespace FW
{
    [Serializable]
    public partial class Item_ { FILE_NAME }
    {
        {ITEM_CLASS_VALUE}
    }


    public partial class Config_{FILE_NAME}:ScriptableObject
    {
          private static Config_{FILE_NAME}_instance = null;
          public List<Item_{FILE_NAME}> list;
          public static Config_ inst
          {
                get
                {
                    if (_instance == null) Init();
                    return _instance;
                }

          }

          public static string CONFIG_NAME = """"""Config_{FILE_NAME}""""""
          public static ConfPath()
          {
                if(Comm.isEditorMode)
                    return """"Assets / MyAssets / Config / """" + CONFIG_NAME + """".asset"""";
                else
                    return CONFIG_NAME;
          }
            
         private static void Init()
         {
            Config_{FILE_NAME} obj;
#if UNITY_EDITOR
            if (Comm.isEditorNoPlaying)
                obj = UnityEditor.AssetDatabase.LoadAssetAtPath < Config_{ FILE_NAME}> (ConfPath());
                    else
                obj = Asset.inst.GetAssetFromCache < Config_{ FILE_NAME}> (ConfPath());

#else
            obj = Asset.inst.GetAssetFromCache<Config_{FILE_NAME}>(ConfPath());
#endif
            _instence = obj;
         }
        
        public Item_{FILE_NAME} GetItemById(int id)
        {
            for(int i = 0;i< list; i++)
            {
                if (list[i].id == id)
                    return list[i];
            }
            return null;
        }           
    }
}      



";
        
    }


}


